#include"protocol.h"


SLNode* BuyListNode(int socket)
{
  SLNode* s = (SLNode*)malloc(sizeof(SLNode));
  if(s == NULL)
  {
    perror("malloc");
    exit(1);

  }
  s->_next = NULL;
  s->_prev = NULL;
  s->_socket = socket;
  return s;

}
int PrepareWork()
{
    int sockfd = socket(AF_INET,SOCK_STREAM,0);//创建套接字
    if(sockfd < 0)
    {
      perror("socket");
      return 1;

    }
    struct sockaddr_in local;//保存套接字信息
    local.sin_family = AF_INET;
    local.sin_addr.s_addr = inet_addr(IP);
    local.sin_port = htons(PORT);
    // 绑定IP和端口号
    if(bind(sockfd,(struct sockaddr*)&local,sizeof(local)) < 0)
    {
      perror("bind");
      return 2;

    }
    printf("bind success\n");
    if(listen(sockfd,5) < 0)//监听
    {
      perror("listen");
      return 3;
    }
    printf("listen success\n");
    return sockfd;
}


SLNode* pHead = NULL;//头结点置为全局变量，函数内部操作时方便，或者传参也行
void* handle(void* arg)//执行服务端给每个客户端发送信息工作
{
  SLNode* node = (SLNode*)arg;
  char buf[NAME+MSG] = {0};
  SLNode* cur = NULL;
  while(1)
  {

      ssize_t re_size = recv(node->_socket,buf,MSG+NAME,0);//0代表阻塞式接收消息
      if(re_size < 0)
      {
         perror("recv client");
         break;
      }
      if(re_size == 0)
      {
          printf("a clent quit...\n");
          break;
      }
      cur = pHead->_next;
      while(cur != NULL)
      {
          ssize_t s = send(cur->_socket,buf,MSG+NAME,0);//采用阻塞式发送数据，
          if(s < 0)
          {
             perror("send");
             exit(3);
          }
          cur = cur->_next;

      }
  }

    node->_prev->_next = node->_next;
    if(node->_next != NULL)//删除节点，节省空间
    {
       node->_next->_prev = node->_prev;    
    } 
    free(node);
    node->_next = NULL;
    node->_prev = NULL;
    close(node->_socket);
    free(cur);
    cur = NULL;
    return NULL;
}
void ServerWork(int sockfd)
{
     pHead = BuyListNode(0);//初始化头结点
     while(1)
    {

        int client_fd = accept(sockfd,NULL,NULL);//与客户端建立链接
        if(client_fd < 0)
        {
          printf("%d\n",client_fd);
          perror("accept");
          break;
        }
      printf("accept success..\n");

      SLNode* newNode = BuyListNode(client_fd);
      if(pHead->_next != NULL)//采用头插法链接节点
      {

        pHead->_next->_prev = newNode;
        newNode->_next = pHead->_next;
      }
      pHead->_next = newNode;
      newNode->_prev = pHead;

      pthread_t tid = 0;
      pthread_create(&tid,NULL,handle,(void*)newNode);
      pthread_detach(tid);//线程分离，线程结束后自己回收
    }

}
int main()
{
  int sockfd = PrepareWork();
  ServerWork(sockfd);
  return 0;

}